home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS 1.31 / antlr / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-10  |  29.2 KB  |  1,193 lines  |  [TEXT/MPS ]

  1. /*
  2.  * main.c -- main program for PCCTS ANTLR.
  3.  *
  4.  * $Id: main.c,v 1.14 1994/12/31 21:02:55 parrt Exp parrt $
  5.  * $Revision: 1.14 $
  6.  *
  7.  * SOFTWARE RIGHTS
  8.  *
  9.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  10.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  11.  * company may do whatever they wish with source code distributed with
  12.  * PCCTS or the code generated by PCCTS, including the incorporation of
  13.  * PCCTS, or its output, into commerical software.
  14.  * 
  15.  * We encourage users to develop software with PCCTS.  However, we do ask
  16.  * that credit is given to us for developing PCCTS.  By "credit",
  17.  * we mean that if you incorporate our source code into one of your
  18.  * programs (commercial product, research project, or otherwise) that you
  19.  * acknowledge this fact somewhere in the documentation, research report,
  20.  * etc...  If you like PCCTS and have developed a nice tool with the
  21.  * output, please mention that you developed it using PCCTS.  In
  22.  * addition, we ask that this header remain intact in our source code.
  23.  * As long as these guidelines are kept, we expect to continue enhancing
  24.  * this system and expect to make other tools available as they are
  25.  * completed.
  26.  *
  27.  * ANTLR 1.31
  28.  * Terence Parr
  29.  * Parr Research Corporation
  30.  * with Purdue University and AHPCRC, University of Minnesota
  31.  * 1989-1995
  32.  */
  33.  
  34. #include <stdio.h>
  35. #ifdef __cplusplus
  36. #ifndef __STDC__
  37. #define __STDC__
  38. #endif
  39. #endif
  40. #include "stdpccts.h"
  41.  
  42. #define MAX_INT_STACK 50
  43. static int istack[MAX_INT_STACK];        /* Int stack */
  44. static int isp = MAX_INT_STACK;
  45.  
  46. static int DontAcceptFiles = 0;            /* if stdin, don't read files */
  47. static int DontAcceptStdin = 0;            /* if files seen first, don't accept stdin */
  48.  
  49.  
  50.         /* C m d - L i n e  O p t i o n  S t r u c t  &  F u n c s */
  51.  
  52. typedef struct _Opt {
  53.             char *option;
  54.             int  arg;
  55. #ifdef __cplusplus
  56.             void (*process)(...);
  57. #else
  58.             void (*process)();
  59. #endif
  60.             char *descr;
  61.         } Opt;
  62.  
  63. #ifdef __STDC__
  64. extern void ProcessArgs(int, char **, Opt *);
  65. #else
  66. extern void ProcessArgs();
  67. #endif
  68.  
  69. static void
  70. #ifdef __STDC__
  71. pStdin( void )
  72. #else
  73. pStdin( )
  74. #endif
  75. {
  76.     if ( DontAcceptStdin )
  77.     {
  78.         warnNoFL("'-' (stdin) ignored as files were specified first");
  79.         return;
  80.     }
  81.  
  82.     require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  83.     FileStr[NumFiles++] = "stdin";
  84.     DontAcceptFiles = 1;
  85. }
  86.  
  87. static void
  88. #ifdef __STDC__
  89. pFile( char *s )
  90. #else
  91. pFile( s )
  92. char *s;
  93. #endif
  94. {
  95.     if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
  96.     if ( DontAcceptFiles )
  97.     {
  98.         warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
  99.         return;
  100.     }
  101.  
  102.     require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  103.     FileStr[NumFiles++] = s;
  104.     DontAcceptStdin = 1;
  105. }
  106.  
  107. static void
  108. #ifdef __STDC__
  109. pLLK( char *s, char *t )
  110. #else
  111. pLLK( s, t )
  112. char *s;
  113. char *t;
  114. #endif
  115. {
  116.     LL_k = atoi(t);
  117.     if ( LL_k <= 0 ) {
  118.         warnNoFL("must have at least one token of lookahead (setting to 1)");
  119.         LL_k = 1;
  120.     }
  121. }
  122.  
  123. static void
  124. #ifdef __STDC__
  125. pCk( char *s, char *t )
  126. #else
  127. pCk( s, t )
  128. char *s;
  129. char *t;
  130. #endif
  131. {
  132.     CLL_k = atoi(t);
  133.     if ( CLL_k <= 0 ) {
  134.         warnNoFL("must have at least one token of look-ahead (setting to 1)");
  135.         CLL_k = 1;
  136.     }
  137. }
  138.  
  139. #ifdef __STDC__
  140. static void pCGen(void)    { CodeGen = FALSE; LexGen = FALSE; }
  141. static void pLGen(void)    { LexGen = FALSE; }
  142. static void pTGen(void)    { TraceGen = TRUE; }
  143. static void pSGen(void)    { GenExprSets = FALSE; }
  144. static void pPrt(void)    { PrintOut = TRUE; pCGen(); pLGen(); }
  145. static void pPrtA(void)    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  146. static void pAst(void)    { GenAST = TRUE; }
  147. static void pANSI(void)    { GenANSI = TRUE; }
  148. static void pCr(void)    { GenCR = TRUE; }
  149. static void pCt(void)    { warnNoFL("-ct option is now the default"); }
  150. static void pLI(void)    { GenLineInfo = TRUE; }
  151. static void pFr(char *s, char *t) {RemapFileName = t;}
  152. static void pFe(char *s, char *t) {ErrFileName = t;}
  153. static void pFl(char *s, char *t) {DlgFileName = t;}
  154. static void pFm(char *s, char *t) {ModeFileName = t;}
  155. static void pFt(char *s, char *t) {DefFileName = t;}
  156. static void pE1(void)    { elevel = 1; }
  157. static void pE2(void)    { elevel = 2; }
  158. static void pE3(void)    { elevel = 3; }
  159. static void pEGen(void)    { GenEClasseForRules = 1; }
  160. static void pDL(void)    { DemandLookahead = 1; }
  161. static void pGHdr(void)    { GenStdPccts = 1; }
  162. static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
  163. static void pW1(void) { WarningLevel = 1; }
  164. static void pW2(void) { WarningLevel = 2; }
  165. static void pCC(void) { GenCC = TRUE; }
  166. #else
  167. static void pCGen()    { CodeGen = FALSE; LexGen = FALSE; }
  168. static void pLGen()    { LexGen = FALSE; }
  169. static void pTGen()    { TraceGen = TRUE; }
  170. static void pSGen()    { GenExprSets = FALSE; }
  171. static void pPrt()        { PrintOut = TRUE; pCGen(); pLGen(); }
  172. static void pPrtA()    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  173. static void pAst()        { GenAST = TRUE; }
  174. static void pANSI()    { GenANSI = TRUE; }
  175. static void pCr()        { GenCR = TRUE; }
  176. static void pCt()        { warnNoFL("-ct option is now the default"); }
  177. static void pLI()        { GenLineInfo = TRUE; }
  178. static void pFr(s,t) char *s, *t; {RemapFileName = t;}
  179. static void pFe(s,t) char *s, *t; {ErrFileName = t;}
  180. static void pFl(s,t) char *s, *t; {DlgFileName = t;}
  181. static void pFm(s,t) char *s, *t; {ModeFileName = t;}
  182. static void pFt(s,t) char *s, *t; {DefFileName = t;}
  183. static void pE1()        { elevel = 1; }
  184. static void pE2()        { elevel = 2; }
  185. static void pE3()        { elevel = 3; }
  186. static void pEGen()    { GenEClasseForRules = 1; }
  187. static void pDL()        { DemandLookahead = 1; }
  188. static void pGHdr()    { GenStdPccts = 1; }
  189. static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
  190. static void pW1() { WarningLevel = 1; }
  191. static void pW2() { WarningLevel = 2; }
  192. static void pCC() { GenCC = TRUE; }
  193. #endif
  194.  
  195. static void
  196. #ifdef __STDC__
  197. pPre( char *s, char *t )
  198. #else
  199. pPre( s, t )
  200. char *s;
  201. char *t;
  202. #endif
  203. {
  204.     RulePrefix = t;
  205. }
  206.  
  207. static void
  208. #ifdef __STDC__
  209. pOut( char *s, char *t )
  210. #else
  211. pOut( s, t )
  212. char *s;
  213. char *t;
  214. #endif
  215. {
  216.     OutputDirectory = t;
  217. }
  218.  
  219. static void
  220. #ifdef __STDC__
  221. pPred( void )
  222. #else
  223. pPred( )
  224. #endif
  225. {
  226.     warnNoFL("-pr is no longer used (predicates employed if present); see -prc");
  227. /*
  228.     if ( DemandLookahead )
  229.         warnNoFL("-gk conflicts with -pr; -gk turned off");
  230.     DemandLookahead = 0;
  231.     HoistPredicateContext = 0;
  232. */
  233. }
  234.  
  235. static void
  236. #ifdef __STDC__
  237. pPredCtx( char *s, char *t )
  238. #else
  239. pPredCtx(s,t)
  240. char *s;
  241. char *t;
  242. #endif
  243. {
  244.     if ( strcmp(t, "on")==0 ) HoistPredicateContext = 1;
  245.     else if ( strcmp(t, "ON")==0 ) HoistPredicateContext = 1;
  246.     else if ( strcmp(t, "off")==0 ) HoistPredicateContext = 0;
  247.     else if ( strcmp(t, "OFF")==0 ) HoistPredicateContext = 0;
  248.     if ( DemandLookahead )
  249.     {
  250.         warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
  251.         DemandLookahead = 0;
  252.     }
  253. }
  254.  
  255. static void
  256. #ifdef __STDC__
  257. pTRes( char *s, char *t )
  258. #else
  259. pTRes( s, t )
  260. char *s;
  261. char *t;
  262. #endif
  263. {
  264.     TreeResourceLimit = atoi(t);
  265.     if ( TreeResourceLimit <= 0 )
  266.     {
  267.         warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
  268.         TreeResourceLimit = -1; /* set to no limit */
  269.     }
  270. }
  271.  
  272. Opt options[] = {
  273. #ifdef __cplusplus
  274.     { "-CC", 0, (void (*)(...)) pCC,    "Generate C++ output (default=FALSE)"},
  275.     { "-ck", 1, (void (*)(...)) pCk,    "Set compressed lookahead depth; fast approximate lookahead"},
  276.     { "-cr", 0, (void (*)(...)) pCr,    "Generate cross reference (default=FALSE)"},
  277.     { "-ct", 0, (void (*)(...)) pCt,    "Do not copy tokens in C++ mode (default=to copy)"},*/
  278.     { "-e1", 0, (void (*)(...)) pE1,    "Ambiguities/errors shown in low detail (default)"},
  279.     { "-e2", 0, (void (*)(...)) pE2,    "Ambiguities/errors shown in more detail"},
  280.     { "-e3", 0, (void (*)(...)) pE3,    "Ambiguities/errors shown in excruciating detail"},
  281.     { "-fe", 1, (void (*)(...)) pFe,    "Rename err.c"},
  282.     { "-fh", 1, (void (*)(...)) pFHdr,    "Rename stdpccts.h header (turns on -gh)"},
  283.     { "-fl", 1, (void (*)(...)) pFl,    "Rename lexical output--parser.dlg"},
  284.     { "-fm", 1, (void (*)(...)) pFm,    "Rename mode.h"},
  285.     { "-fr", 1, (void (*)(...)) pFr,    "Rename remap.h"},
  286.     { "-ft", 1, (void (*)(...)) pFt,    "Rename tokens.h"},
  287.     { "-ga", 0, (void (*)(...)) pANSI,    "Generate ANSI-compatible code (default=FALSE)"},
  288.     { "-gc", 0, (void (*)(...)) pCGen,    "Do not generate output parser code (default=FALSE)"},
  289.     { "-gd", 0, (void (*)(...)) pTGen,    "Generate code to trace rule invocation (default=FALSE)"},
  290.     { "-ge", 0, (void (*)(...)) pEGen,    "Generate an error class for each non-terminal (default=FALSE)"},
  291.     { "-gh", 0, (void (*)(...)) pGHdr,    "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  292.     { "-gk", 0, (void (*)(...)) pDL,    "Generate parsers that delay lookahead fetches 'til needed"},
  293.     { "-gl", 0, (void (*)(...)) pLI,    "Generate line info about grammar actions in C parser"},
  294.     { "-gp", 1, (void (*)(...)) pPre,    "Prefix all generated rule functions with a string"},
  295.     { "-gs", 0, (void (*)(...)) pSGen,    "Do not generate sets for token expression lists (default=FALSE)"},
  296.     { "-gt", 0, (void (*)(...)) pAst,    "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  297.     { "-gx", 0, (void (*)(...)) pLGen,    "Do not generate lexical (dlg-related) files (default=FALSE)"},
  298.     { "-k",  1, (void (*)(...)) pLLK,    "Set full LL(k) lookahead depth (default==1)"},
  299.     { "-o",  1, (void (*)(...)) pOut,    OutputDirectoryOption},
  300.     { "-p",  0, (void (*)(...)) pPrt,    "Print out the grammar w/o actions (default=no)"},
  301.     { "-pa", 0, (void (*)(...)) pPrtA,    "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  302.     { "-pr",0, (void (*)(...)) pPred,    "no longer used; predicates employed if present"},
  303.     { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  304.        { "-rl", 1, (void (*)(...)) pTRes,    "Limit max # of tree nodes used by grammar analysis"},
  305.     { "-w1", 0, (void (*)(...)) pW1,    "Set the warning level to 1 (default)"},
  306.     { "-w2", 0, (void (*)(...)) pW2,    "Ambiguities yield warnings even if predicates or (...)? block"},
  307.     { "-",   0, (void (*)(...)) pStdin,    "Read grammar from stdin" },
  308.     { "*",   0, (void (*)(...)) pFile,     "" },    /* anything else is a file */
  309. #else
  310.     { "-CC", 0, pCC,    "Generate C++ output (default=FALSE)"},
  311.     { "-cr", 0, pCr,    "Generate cross reference (default=FALSE)"},
  312.     { "-ct", 0, pCt,    "Do not copy tokens in C++ mode (default=to copy)"},
  313.     { "-ck", 1, pCk,    "Set compressed lookahead depth; fast approximate lookahead"},
  314.     { "-e1", 0, pE1,    "Ambiguities/errors shown in low detail (default)"},
  315.     { "-e2", 0, pE2,    "Ambiguities/errors shown in more detail"},
  316.     { "-e3", 0, pE3,    "Ambiguities/errors shown in excrutiating detail"},
  317.     { "-fe", 1, pFe,    "Rename err.c"},
  318.     { "-fh", 1, pFHdr,    "Rename stdpccts.h header (turns on -gh)"},
  319.     { "-fl", 1, pFl,    "Rename lexical output--parser.dlg"},
  320.     { "-fm", 1, pFm,    "Rename mode.h"},
  321.     { "-fr", 1, pFr,    "Rename remap.h"},
  322.     { "-ft", 1, pFt,    "Rename tokens.h"},
  323.     { "-ga", 0, pANSI,    "Generate ANSI-compatible code (default=FALSE)"},
  324.     { "-gc", 0, pCGen,    "Do not generate output parser code (default=FALSE)"},
  325.     { "-gd", 0, pTGen,    "Generate code to trace rule invocation (default=FALSE)"},
  326.     { "-ge", 0, pEGen,    "Generate an error class for each non-terminal (default=FALSE)"},
  327.     { "-gh", 0, pGHdr,    "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  328.     { "-gk", 0, pDL,    "Generate parsers that delay lookahead fetches 'til needed"},
  329.     { "-gl", 0, pLI,    "Generate line info about grammar actions in C parser"},
  330.     { "-gp", 1, pPre,    "Prefix all generated rule functions with a string"},
  331.     { "-gs", 0, pSGen,    "Do not generate sets for token expression lists (default=FALSE)"},
  332.     { "-gt", 0, pAst,    "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  333.     { "-gx", 0, pLGen,    "Do not generate lexical (dlg-related) files (default=FALSE)"},
  334.     { "-k",  1, pLLK,    "Set full LL(k) lookahead depth (default==1)"},
  335.     { "-o",  1, pOut,    OutputDirectoryOption},
  336.     { "-p",  0, pPrt,    "Print out the grammar w/o actions (default=no)"},
  337.     { "-pa", 0, pPrtA,    "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  338.     { "-pr",0, pPred,    "no longer used; predicates employed if present"},
  339.     { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  340.        { "-rl", 1, pTRes,    "Limit max # of tree nodes used by grammar analysis"},
  341.     { "-w1", 0, pW1,    "Set the warning level to 1 (default)"},
  342.     { "-w2", 0, pW2,    "Ambiguities yield warnings even if predicates or (...)? block"},
  343.     { "-",   0, pStdin,    "Read grammar from stdin" },
  344.     { "*",   0, pFile,     "" },    /* anything else is a file */
  345. #endif
  346.     { NULL,  0, NULL }
  347. };
  348.  
  349. void readDescr();
  350. void cleanUp();
  351.  
  352. #ifdef __STDC__
  353. static void buildRulePtr( void );
  354. static void help( void );
  355. static void init( void );
  356. static void CompleteTokenSetRefs( void );
  357. static void ensure_no_C_file_collisions(char *);
  358. #else
  359. static void buildRulePtr( );
  360. static void help( );
  361. static void init( );
  362. static void CompleteTokenSetRefs( );
  363. static void ensure_no_C_file_collisions();
  364. #endif
  365.  
  366.                                 /* M a i n */
  367.  
  368. int
  369. #ifdef __STDC__
  370. main( int argc, char *argv[] )
  371. #else
  372. main( argc, argv )
  373. int argc;
  374. char *argv[];
  375. #endif
  376. {
  377.     int i;
  378.     static char EPSTR[] = "[Ep]";
  379.  
  380.     special_inits();
  381.  
  382.     fprintf(stderr, "Antlr parser generator   Version %s   1989-1995\n", Version);
  383.     if ( argc == 1 ) { help(); zzDIE; }
  384.     ProcessArgs(argc-1, &(argv[1]), options);
  385.  
  386.     /* Fix lookahead depth */
  387.     /* Compressed lookahead must always be larger than or equal to full lookahead */
  388.     if ( CLL_k < LL_k  && CLL_k>0 )
  389.     {
  390.         warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
  391.         CLL_k = LL_k;
  392.     }
  393.     if ( CLL_k == -1 ) CLL_k = LL_k;
  394.     OutputLL_k = CLL_k;
  395.     if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
  396.         int n;
  397.         for(n=1; n<CLL_k; n<<=1) {;}
  398.         OutputLL_k = n;
  399.     }
  400.  
  401.     fpTrans = &(C_Trans[0]);        /* Translate to C Language */
  402.     fpJTrans = &(C_JTrans[0]);
  403.     init();
  404.     lexclass(LexStartSymbol);
  405.  
  406.     readDescr();
  407.     LastTokenCounted = TokenNum;
  408.     RemapForcedTokens();
  409.     if ( CannotContinue ) {cleanUp(); zzDIE;}
  410.     if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
  411.     if ( WarningLevel>1 && HdrAction == NULL )
  412.        warnNoFL("no #header action was found");
  413.  
  414.     EpToken = addTname(EPSTR);        /* add imaginary token epsilon */
  415.     set_orel(EpToken, &imag_tokens);
  416.  
  417.     /* this won't work for hand-built scanners since EofToken is not
  418.      * known.  Forces EOF to be token type 1.
  419.      */
  420.     set_orel(EofToken, &imag_tokens);
  421.  
  422.     set_size(NumWords(TokenNum-1));
  423.  
  424.     /* compute the set of all known token types 
  425.      * It represents the set of tokens from 1 to last_token_num + the
  426.      * reserved positions above that (if any).  Don't include the set of
  427.      * imaginary tokens such as the token/error classes or EOF.
  428.      */
  429.     {
  430.         set a;
  431.         a = set_dup(reserved_positions);
  432.         for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
  433.         all_tokens = set_dif(a, imag_tokens);
  434.         set_free(a);
  435.     }
  436.  
  437.     ComputeTokSets();
  438.     CompleteTokenSetRefs();
  439.  
  440.     if ( CodeGen ) genDefFile();    /* create tokens.h */
  441.     if ( LexGen ) genLexDescr();    /* create parser.dlg */
  442.  
  443.     if ( GenStdPccts )
  444.     {
  445.         FILE *f = fopen(OutMetaName(stdpccts), "w");
  446.         if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
  447.         else
  448.         {
  449.             special_fopen_actions(OutMetaName(stdpccts));
  450.             genStdPCCTSIncludeFile(f);
  451.             fclose(f);
  452.         }
  453.     }
  454.  
  455.     buildRulePtr();                    /* create mapping from rule # to RuleBlk junction */
  456.     ComputeErrorSets();
  457.     FoLink( (Node *)SynDiag );        /* add follow links to end of all rules */
  458.     
  459.     if ( GenCR ) GenCrossRef( SynDiag );
  460.  
  461.     if ( CodeGen )
  462.     {
  463.         if ( SynDiag == NULL )
  464.         {
  465.             warnNoFL("no grammar description recognized");
  466.             cleanUp();
  467.             zzDIE;
  468.         }
  469.         else if ( !GenCC ) {
  470.             ErrFile = fopen(OutMetaName(ErrFileName), "w");
  471.             require(ErrFile != NULL, "main: can't open err file");
  472.             special_fopen_actions(OutMetaName(ErrFileName));
  473.             NewSetWd();
  474.             GenErrHdr();
  475.             TRANS(SynDiag);            /* Translate to the target language */
  476.             DumpSetWd();
  477.             DumpRemainingTokSets();
  478.             fclose( ErrFile );
  479.         }
  480.         else {
  481.             strcpy(Parser_h_Name, CurrentClassName);
  482.             strcat(Parser_h_Name, ".h");
  483.             strcpy(Parser_c_Name, CurrentClassName);
  484.             strcat(Parser_c_Name, CPP_FILE_SUFFIX);
  485.             ensure_no_C_file_collisions(Parser_c_Name);
  486.             Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
  487.             require(Parser_h != NULL, "main: can't open class Parserx.h file");
  488.             special_fopen_actions(OutMetaName(Parser_h_Name));
  489.             Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
  490.             require(Parser_c != NULL, "main: can't open class Parserx.c file");
  491.             special_fopen_actions(OutMetaName(Parser_c_Name));
  492.             GenParser_h_Hdr();
  493.             GenParser_c_Hdr();
  494.             NewSetWd();
  495.             TRANS(SynDiag);            /* Translate to the target language */
  496.             DumpSetWd();
  497.             GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
  498.             /* Dump class members */
  499.             if ( class_actions != NULL )
  500.             {
  501.                 ListNode *p;
  502.                 for (p = class_actions->next; p!=NULL; p=p->next)
  503.                 {
  504.                     UserAction *ua = (UserAction *)p->elem;
  505.                     dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
  506.                 }
  507.             }
  508.             DumpRemainingTokSets();
  509.             fprintf(Parser_h, "};\n");
  510.             fprintf(Parser_h, "\n#endif /* %s_h */\n", CurrentClassName);
  511.             fclose( Parser_h );
  512.             fclose( Parser_c );
  513.         }
  514.     }
  515.  
  516.     if ( PrintOut )
  517.     {
  518.         if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
  519.         else PRINT(SynDiag);
  520.     }
  521.  
  522.     GenRemapFile();                    /* create remap.h */
  523.  
  524.     cleanUp();
  525. #ifdef VAXC
  526.     return 1;               /* report all is well for make etc... */
  527. #else
  528.     return 0;               /* report all is well for make etc... */
  529. #endif
  530. }
  531.  
  532. static void
  533. #ifdef __STDC__
  534. init( void )
  535. #else
  536. init( )
  537. #endif
  538. {
  539.     SignalEntry *q;
  540.  
  541.     Tname = newHashTable();
  542.     Rname = newHashTable();
  543.     Fcache = newHashTable();
  544.     Tcache = newHashTable();
  545.     Sname = newHashTable();
  546.     /* Add default signal names */
  547.     q = (SignalEntry *)hash_add(Sname,
  548.                               "NoViableAlt",
  549.                               (Entry *)newSignalEntry("NoViableAlt"));
  550.     require(q!=NULL, "cannot alloc signal entry");
  551.     q->signum = sigNoViableAlt;
  552.     q = (SignalEntry *)hash_add(Sname,
  553.                               "MismatchedToken",
  554.                               (Entry *)newSignalEntry("MismatchedToken"));
  555.     require(q!=NULL, "cannot alloc signal entry");
  556.     q->signum = sigMismatchedToken;
  557.     q = (SignalEntry *)hash_add(Sname,
  558.                               "NoSemViableAlt",
  559.                               (Entry *)newSignalEntry("NoSemViableAlt"));
  560.     require(q!=NULL, "cannot alloc signal entry");
  561.     q->signum = sigNoSemViableAlt;
  562.     
  563.     reserved_positions = empty;
  564.     all_tokens = empty;
  565.     imag_tokens = empty;
  566.     tokclasses = empty;
  567.     TokenStr = (char **) calloc(TSChunk, sizeof(char *));
  568.     require(TokenStr!=NULL, "main: cannot allocate TokenStr");
  569.     FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
  570.     require(FoStack!=NULL, "main: cannot allocate FoStack");
  571.     FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
  572.     require(FoTOS!=NULL, "main: cannot allocate FoTOS");
  573.     Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
  574.     require(Cycles!=NULL, "main: cannot allocate Cycles List");
  575. }
  576.  
  577. static void
  578. #ifdef __STDC__
  579. help( void )
  580. #else
  581. help( )
  582. #endif
  583. {
  584.     Opt *p = options;
  585.     fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
  586.     while ( *(p->option) != '*' )
  587.     {
  588.         fprintf(stderr, "\t%-4s %s   %s\n",
  589.                         p->option,
  590.                         (p->arg)?"___":"   ",
  591.                         p->descr);
  592.         p++;
  593.     }
  594. }
  595.  
  596. /* The RulePtr array is filled in here.  RulePtr exists primarily
  597.  * so that sets of rules can be maintained for the FOLLOW caching
  598.  * mechanism found in rJunc().  RulePtr maps a rule num from 1 to n
  599.  * to a pointer to its RuleBlk junction where n is the number of rules.
  600.  */
  601. static void
  602. #ifdef __STDC__
  603. buildRulePtr( void )
  604. #else
  605. buildRulePtr( )
  606. #endif
  607. {
  608.     int r=1;
  609.     Junction *p  = SynDiag;
  610.     RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
  611.     require(RulePtr!=NULL, "cannot allocate RulePtr array");
  612.     
  613.     while ( p!=NULL )
  614.     {
  615.         require(r<=NumRules, "too many rules???");
  616.         RulePtr[r++] = p;
  617.         p = (Junction *)p->p2;
  618.     }
  619. }
  620.  
  621. void
  622. #ifdef __STDC__
  623. dlgerror(const char *s)
  624. #else
  625. dlgerror(s)
  626. char *s;
  627. #endif
  628. {
  629.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  630.     fprintf(stderr, " lexical error: %s (text was '%s')\n",
  631.                     ((s == NULL) ? "Lexical error" : s), zzlextext);
  632. }
  633.  
  634. void
  635. #ifdef __STDC__
  636. readDescr( void )
  637. #else
  638. readDescr( )
  639. #endif
  640. {
  641.     zzerr = dlgerror;
  642.     input = NextFile();
  643.     if ( input==NULL ) fatal("No grammar description found (exiting...)");
  644.     ANTLR(grammar(), input);
  645. }
  646.  
  647. FILE *
  648. #ifdef __STDC__
  649. NextFile( void )
  650. #else
  651. NextFile( )
  652. #endif
  653. {
  654.     FILE *f;
  655.  
  656.     for (;;)
  657.     {
  658.         CurFile++;
  659.         if ( CurFile >= NumFiles ) return(NULL);
  660.         if ( strcmp(FileStr[CurFile],"stdin") == 0 ) return stdin;
  661.         f = fopen(FileStr[CurFile], "r");
  662.         if ( f == NULL )
  663.         {
  664.             warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
  665.         }
  666.         else
  667.         {
  668.             return(f);
  669.         }
  670.     }
  671. }
  672.  
  673. /*
  674.  * Return a string corresponding to the output file name associated
  675.  * with the input file name passed in.
  676.  *
  677.  * Observe the following rules:
  678.  *
  679.  *        f.e        --> f".c"
  680.  *        f        --> f".c"
  681.  *        f.        --> f".c"
  682.  *        f.e.g    --> f.e".c"
  683.  *
  684.  * Where f,e,g are arbitrarily long sequences of characters in a file
  685.  * name.
  686.  *
  687.  * In other words, if a ".x" appears on the end of a file name, make it
  688.  * ".c".  If no ".x" appears, append ".c" to the end of the file name.
  689.  *
  690.  * C++ mode using .C not .c.
  691.  *
  692.  * Use malloc() for new string.
  693.  */
  694. char *
  695. #ifdef __STDC__
  696. outname( char *fs )
  697. #else
  698. outname( fs )
  699. char *fs;
  700. #endif
  701. {
  702.     static char buf[MaxFileName+1];
  703.     char *p;
  704.     require(fs!=NULL&&*fs!='\0', "outname: NULL filename");
  705.  
  706.     p = buf;
  707.     strcpy(buf, fs);
  708.     while ( *p != '\0' )  {p++;}            /* Stop on '\0' */
  709.     while ( *p != '.' && p != buf ) {--p;}    /* Find '.' */
  710.     if ( p != buf ) *p = '\0';                /* Found '.' */
  711.     require(strlen(buf) + 2 < MaxFileName, "outname: filename too big");
  712.     if ( GenCC ) strcat(buf, CPP_FILE_SUFFIX);
  713.     else strcat(buf, ".c");
  714.     return( buf );
  715. }
  716.  
  717. void
  718. #ifdef __STDC__
  719. fatalFL( char *err_, char *f, int l )
  720. #else
  721. fatalFL( err_, f, l )
  722. char *err_;
  723. char *f;
  724. int l;
  725. #endif
  726. {
  727.     fprintf(stderr, ErrHdr, f, l);
  728.     fprintf(stderr,    " %s\n", err_);
  729.     cleanUp();
  730.     exit(1);
  731. }
  732.  
  733. void
  734. #ifdef __STDC__
  735. fatal_intern( char *err_, char *f, int l )
  736. #else
  737. fatal_intern( err_, f, l )
  738. char *err_;
  739. char *f;
  740. int l;
  741. #endif
  742. {
  743.     fprintf(stderr, ErrHdr, f, l);
  744.     fprintf(stderr,    " #$%%*&@# internal error: %s\n", err_);
  745.     fprintf(stderr, ErrHdr, f, l);
  746.     fprintf(stderr, " [complain to nearest government official\n");
  747.     fprintf(stderr, ErrHdr, f, l);
  748.     fprintf(stderr, "  or send hate-mail to parrt@acm.org;\n");
  749.     fprintf(stderr, ErrHdr, f, l);
  750.     fprintf(stderr, "  please pray to the ``bug'' gods that there is a trival fix.]\n");
  751.     cleanUp();
  752.     exit(1);
  753. }
  754.  
  755. void
  756. #ifdef __STDC__
  757. cleanUp( void )
  758. #else
  759. cleanUp( )
  760. #endif
  761. {
  762.     if ( DefFile != NULL) fclose( DefFile );
  763. }
  764.  
  765. /* sprintf up to 3 strings */
  766. char *
  767. #ifdef __STDC__
  768. eMsg3( char *s, char *a1, char *a2, char *a3 )
  769. #else
  770. eMsg3( s, a1, a2, a3 )
  771. char *s;
  772. char *a1;
  773. char *a2;
  774. char *a3;
  775. #endif
  776. {
  777.     static char buf[250];            /* DANGEROUS as hell !!!!!! */
  778.     
  779.     sprintf(buf, s, a1, a2, a3);
  780.     return( buf );
  781. }
  782.  
  783. /* sprintf a decimal */
  784. char *
  785. #ifdef __STDC__
  786. eMsgd( char *s, int d )
  787. #else
  788. eMsgd( s, d )
  789. char *s;
  790. int d;
  791. #endif
  792. {
  793.     static char buf[250];            /* DANGEROUS as hell !!!!!! */
  794.     
  795.     sprintf(buf, s, d);
  796.     return( buf );
  797. }
  798.  
  799. void
  800. #ifdef __STDC__
  801. s_fprT( FILE *f, set e )
  802. #else
  803. s_fprT( f, e )
  804. FILE *f;
  805. set e;
  806. #endif
  807. {
  808.     register unsigned *p;
  809.     unsigned *q;
  810.  
  811.     if ( set_nil(e) ) return;
  812.     if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
  813.     fprintf(f, "{");
  814.     while ( *p != nil )
  815.     {
  816.         fprintf(f, " %s", TerminalString(*p));
  817.         p++;
  818.     }
  819.     fprintf(f, " }");
  820.     free((char *)q);
  821. }
  822.  
  823. /* Return the token name or regular expression for a token number. */
  824. char *
  825. #ifdef __STDC__
  826. TerminalString( int token )
  827. #else
  828. TerminalString( token )
  829. int token;
  830. #endif
  831. {
  832.     int j;
  833.  
  834.     /* look in all lexclasses for the token */
  835.     if ( TokenString(token) != NULL ) return TokenString(token);
  836.     for (j=0; j<NumLexClasses; j++)
  837.     {
  838.         lexmode(j);
  839.         if ( ExprString(token) != NULL ) return ExprString(token);
  840.     }
  841.     require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
  842.     return "invalid";
  843. }
  844.  
  845.                     /* S i m p l e  I n t  S t a c k */
  846.  
  847. void
  848. #ifdef __STDC__
  849. pushint( int i )
  850. #else
  851. pushint( i )
  852. int i;
  853. #endif
  854. {
  855.     require(isp>0, "pushint: stack overflow");
  856.     istack[--isp] = i;
  857. }
  858.  
  859. int
  860. #ifdef __STDC__
  861. popint( void )
  862. #else
  863. popint( )
  864. #endif
  865. {
  866.     require(isp<MAX_INT_STACK, "popint: stack underflow");
  867.     return istack[isp++];
  868. }
  869.  
  870. int
  871. #ifdef __STDC__
  872. istacksize( void )
  873. #else
  874. istacksize( )
  875. #endif
  876. {
  877.     return MAX_INT_STACK-isp;
  878. }
  879.  
  880. void
  881. #ifdef __STDC__
  882. istackreset( void )
  883. #else
  884. istackreset( )
  885. #endif
  886. {
  887.     isp = MAX_INT_STACK;
  888. }
  889.  
  890. int
  891. #ifdef __STDC__
  892. istackempty( void )
  893. #else
  894. istackempty( )
  895. #endif
  896. {
  897.     return isp==MAX_INT_STACK;
  898. }
  899.  
  900. int
  901. #ifdef __STDC__
  902. topint( void )
  903. #else
  904. topint( )
  905. #endif
  906. {
  907.     require(isp<MAX_INT_STACK, "topint: stack underflow");
  908.     return istack[isp];
  909. }
  910.  
  911. void
  912. #ifdef __STDC__
  913. ProcessArgs( int argc, char **argv, Opt *options )
  914. #else
  915. ProcessArgs( argc, argv, options )
  916. int argc;
  917. char **argv;
  918. Opt *options;
  919. #endif
  920. {
  921.     Opt *p;
  922.     require(argv!=NULL, "ProcessArgs: command line NULL");
  923.  
  924.     while ( argc-- > 0 )
  925.     {
  926.         p = options;
  927.         while ( p->option != NULL )
  928.         {
  929.             if ( strcmp(p->option, "*") == 0 ||
  930.                  strcmp(p->option, *argv) == 0 )
  931.             {
  932.                 if ( p->arg )
  933.                 {
  934.                     (*p->process)( *argv, *(argv+1) );
  935.                     argv++;
  936.                     argc--;
  937.                 }
  938.                 else
  939.                     (*p->process)( *argv );
  940.                 break;
  941.             }
  942.             p++;
  943.         }
  944.         argv++;
  945.     }
  946. }
  947.  
  948. /* Go back into the syntax diagram and compute all meta tokens; i.e.
  949.  * turn all '.', ranges, token class refs etc... into actual token sets
  950.  */
  951. static void
  952. CompleteTokenSetRefs()
  953. {
  954.     ListNode *p;
  955.  
  956.     if ( MetaTokenNodes==NULL ) return;
  957.     for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
  958.     {
  959.         set a,b;
  960.  
  961.         TokNode *q = (TokNode *)p->elem;
  962.         if ( q->wild_card )
  963.         {
  964.             q->tset = all_tokens;
  965.         }
  966.         else if ( q->tclass!=NULL )
  967.         {
  968.             if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
  969.             else q->tset = q->tclass->tset;
  970.         }
  971.         else if ( q->upper_range!=0 )
  972.         {
  973.             /* we have a range on our hands: make a set from q->token .. q->upper_range */
  974.             int i;
  975.             a = empty;
  976.             for (i=q->token; i<=(int)q->upper_range; i++) { set_orel(i, &a); }
  977.             q->tset = a;
  978.         }
  979.         /* at this point, it can only be a complemented single token */
  980.         else if ( q->complement )
  981.         {
  982.             a = set_of(q->token);
  983.             b = set_dif(all_tokens, a);
  984.             set_free(a);
  985.             q->tset=b;
  986.         }
  987.         else fatal("invalid meta token");
  988.     }
  989. }
  990.  
  991. char *
  992. #ifdef __STDC__
  993. OutMetaName(char *n)
  994. #else
  995. OutMetaName(n)
  996. char *n;
  997. #endif
  998. {
  999.     static char buf[MaxFileName+1];
  1000.  
  1001.     if ( strcmp(OutputDirectory,TopDirectory)==0 ) return n;
  1002.     strcpy(buf, OutputDirectory);
  1003.     if ( strcmp(&buf[strlen(buf) - 1], DirectorySymbol ) )
  1004.         strcat(buf, DirectorySymbol);
  1005.     strcat(buf, n);
  1006.     return buf;
  1007. }
  1008.  
  1009. static void
  1010. #ifdef __STDC__
  1011. ensure_no_C_file_collisions(char *class_c_file)
  1012. #else
  1013. ensure_no_C_file_collisions(class_c_file)
  1014. char *class_c_file;
  1015. #endif
  1016. {
  1017.     int i;
  1018.  
  1019.     for (i=0; i<NumFiles; i++)
  1020.     {
  1021. #ifdef PC
  1022.         /* assume that file names are case insensitive */
  1023.         if ( strcasecmp(outname(FileStr[i]), class_c_file)==0 )
  1024. #else
  1025.         if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
  1026. #endif
  1027.         {
  1028.             fatal(eMsg1("class def output file conflicts with parser output file: %s",
  1029.                         outname(FileStr[i])));
  1030.         }
  1031.     }
  1032. }
  1033.  
  1034. void
  1035. #ifdef __STDC__
  1036. warnNoFL(char *err)
  1037. #else
  1038. warnNoFL(err)
  1039. char *err;
  1040. #endif
  1041. {
  1042.     fprintf(stderr, "warning: %s\n", err);
  1043. }
  1044.  
  1045. void
  1046. #ifdef __STDC__
  1047. warnFL(char *err,char *f,int l)
  1048. #else
  1049. warnFL(err,f,l)
  1050. char *f;
  1051. int l;
  1052. char *err;
  1053. #endif
  1054. {
  1055.     fprintf(stderr, ErrHdr, f, l);                        
  1056.     fprintf(stderr, " warning: %s\n", err);
  1057. }
  1058.  
  1059. void
  1060. #ifdef __STDC__
  1061. warn(char *err)                                                
  1062. #else
  1063. warn(err)                                                
  1064. char *err;
  1065. #endif
  1066. {
  1067.     /* back up the file number if we hit an error at the end of the last file */
  1068.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1069.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1070.     fprintf(stderr, " warning: %s\n", err);
  1071. }
  1072.  
  1073. void
  1074. #ifdef __STDC__
  1075. warnNoCR( char *err )
  1076. #else
  1077. warnNoCR( err )                                            
  1078. char *err;
  1079. #endif
  1080. {
  1081.     /* back up the file number if we hit an error at the end of the last file */
  1082.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1083.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1084.     fprintf(stderr, " warning: %s", err);
  1085. }
  1086.  
  1087. void
  1088. #ifdef __STDC__
  1089. errNoFL(char *err)
  1090. #else
  1091. errNoFL(err)
  1092. char *err;
  1093. #endif
  1094. {
  1095.     fprintf(stderr, "error: %s\n", err);
  1096. }
  1097.  
  1098. void
  1099. #ifdef __STDC__
  1100. errFL(char *err,char *f,int l)                                            
  1101. #else
  1102. errFL(err,f,l)                                            
  1103. char *err;
  1104. char *f;
  1105. int l;
  1106. #endif
  1107. {
  1108.     fprintf(stderr, ErrHdr, f, l);                        
  1109.     fprintf(stderr, " error: %s\n", err);
  1110. }
  1111.  
  1112. void
  1113. #ifdef __STDC__
  1114. err(char *err)                                                
  1115. #else
  1116. err(err)                                                
  1117. char *err;
  1118. #endif
  1119. {
  1120.     /* back up the file number if we hit an error at the end of the last file */
  1121.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1122.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1123.     fprintf(stderr, " error: %s\n", err);
  1124. }
  1125.  
  1126. void
  1127. #ifdef __STDC__
  1128. errNoCR( char *err )                                            
  1129. #else
  1130. errNoCR( err )                                            
  1131. char *err;
  1132. #endif
  1133. {
  1134.     /* back up the file number if we hit an error at the end of the last file */
  1135.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1136.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1137.     fprintf(stderr, " error: %s", err);
  1138. }
  1139.  
  1140. UserAction *
  1141. #ifdef __STDC__
  1142. newUserAction(char *s)
  1143. #else
  1144. newUserAction(s)
  1145. char *s;
  1146. #endif
  1147. {
  1148.     UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));
  1149.     require(ua!=NULL, "cannot allocate UserAction");
  1150.  
  1151.     ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
  1152.     strcpy(ua->action, s);
  1153.     return ua;
  1154. }
  1155.  
  1156. /* Added by TJP September 1994 */
  1157. /* Take in file.h and return file_h; names w/o '.'s are left alone */
  1158. char *
  1159. #ifdef __USE_PROTOS
  1160. gate_symbol(char *name)
  1161. #else
  1162. gate_symbol(name)
  1163. char *name;
  1164. #endif
  1165. {
  1166.     static char buf[100];
  1167.     char *p;
  1168.     sprintf(buf, "%s", name);
  1169.  
  1170.     for (p=buf; *p!='\0'; p++)
  1171.     {
  1172.         if ( *p=='.' ) *p = '_';
  1173.     }
  1174.     return buf;
  1175. }
  1176.  
  1177. char *
  1178. #ifdef __USE_PROTOS
  1179. makeAltID(int blockid, int altnum)
  1180. #else
  1181. makeAltID(blockid, altnum)
  1182. int blockid;
  1183. int altnum;
  1184. #endif
  1185. {
  1186.     static char buf[100];
  1187.     char *p;
  1188.     sprintf(buf, "_blk%d_alt%d", blockid, altnum);
  1189.     p = malloc(strlen(buf)+1);
  1190.     strcpy(p, buf);
  1191.     return p;
  1192. }
  1193.